﻿#pragma once

#include "Lock.h"
#include "Event.h"
#include "atom.h"
#include "SyncFixedQueue.h"

#ifdef WIN32
# include "ThreadWin32.h"
#else
# include "ThreadPOSIX.h"
#endif



namespace df
{
	template<uint32_t _Size>
	class ThreadPool
	{
	public:
		static_assert(_Size > 0, "ThreadPool size can't empty");

		ThreadPool()
		{
			for (int i = 0; i < _Size; i++)
			{

				Thread::Start([&] {
					for (;;)
					{
						bool hasTask = false;
						std::function<void()> func;
						{
							std::unique_lock<std::mutex> lck(mtx_);
							cv_.wait(lck); // 当前线程被阻塞, 当全局标志位变为 true 之后,
							if (exitCount_ > 0) {
								exitCount_--;
								return;
							}
							hasTask = task_.size() > 0;
							if (hasTask)
							{
								func = std::move(task_.front());
								task_.pop();
							}

						}

						while (hasTask)
						{

							try
							{
								if (func)
									func();
							}DF_CATCH_ALL;

							func = nullptr;

							std::unique_lock<std::mutex> lck(mtx_);
							if (exitCount_ > 0) {
								exitCount_--;
								return;
							}
							hasTask = task_.size() > 0;
							if (hasTask)
							{
								func = std::move(task_.front());
								task_.pop();
							}
						}


					}
				});
			}
		}
		~ThreadPool()
		{
			exitCount_ = _Size + 1;
			cv_.notify_all();
			while (exitCount_ > 1) {
				df::ThreadSleep(1);
			}
		}

		template<class _Func>
		void Run(_Func func)
		{
			std::unique_lock <std::mutex> lck(mtx_);

			task_.push(func);

			cv_.notify_one();

		}
	private:
		std::queue<std::function<void()>> task_; //任务队列
		std::mutex mtx_; // 全局互斥锁.
		std::condition_variable cv_; // 全局条件变量.
		uint32_t exitCount_ = 0;
		DF_DISABLE_COPY_ASSIGN(ThreadPool);
	};


	///线程池
	//class Async
	//{
	//private:
	//	const static int maxThreadNum_ = 128;

	//	static SyncFixedQueue<Async*, maxThreadNum_> & GetFreeList()
	//	{
	//		static SyncFixedQueue<Async*, maxThreadNum_> arr;
	//		return arr;
	//	}
	//public:
	//	template<class LamT>
	//	Async(LamT && cb)
	//		: wait_(TRUE)
	//		, callBack_(cb)
	//	{
	//		Thread::Start([&]{
	//			for (;;)
	//			{
	//				this->wait_.Wait();

	//				try
	//				{
	//					callBack_();
	//				}DF_CATCH_ALL;


	//				callBack_ = [](){};

	//				if (!GetFreeList().Add(this))
	//				{
	//					delete this;
	//					break;
	//				}
	//			}
	//		});
	//	}

	//	

	//	inline static bool PopAsync(Async *& as)
	//	{
	//		return GetFreeList().Pop(as);
	//	}

	//	Event wait_;
	//	std::function<void(void) > callBack_;
	//private:






	//	DF_DISABLE_COPY_ASSIGN(Async);
	//};



	////*******************************************
	//// Summary : 异步执行cb
	//// Parameter -  cb : 要执行的函数:void(void)
	////*******************************************
	//template<class LamT>
	//static void AsyncStart(LamT cb)
	//{
	//	Async * as = nullptr;
	//	if (Async::PopAsync(as))
	//	{
	//		as->callBack_ = cb;
	//		as->wait_.Set();
	//	}
	//	else
	//		as = new Async(cb);

	//}

}
